home *** CD-ROM | disk | FTP | other *** search
/ Aminet 51 / Aminet 51 (2002)(GTI - Schatztruhe)[!][Oct 2002].iso / Aminet / dev / gg / tcpbug.lha / tcpbug / ip / tcp_open.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-04  |  2.3 KB  |  96 lines

  1. #include <stddef.h>
  2. #include <errno.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <assert.h>
  6.  
  7. #include <unistd.h>
  8. #include <sys/types.h>
  9. #include <sys/socket.h>
  10. #include <netinet/in.h>
  11. #include <arpa/inet.h>
  12. #include <netdb.h>
  13.  
  14. #include "ip_misc.h"
  15.  
  16.  
  17. #define    Export
  18.  
  19.  
  20.  
  21. /*
  22.  *  Open a TCP connection to port REMOTE_PORT on host REMOTE_HOST.
  23.  *  If LOCAL_HOST is not NULL, the local end of the connection is
  24.  *  bound to that address.  If LOCAL_PORT is not NULL, the local
  25.  *  end of the connection is bound to that port.
  26.  *  Hosts may be given as either a numeric IP address or as a host
  27.  *  names.  Ports may be given as either a decimal port number, or
  28.  *  as a symbolic service name.
  29.  *  
  30.  *  Returns the file descriptor for the connection, or negative on
  31.  *  errors.
  32.  */
  33. Export    int
  34. tcp_open(const char *remote_host,
  35.      const char *remote_port,
  36.      const char *local_host,
  37.      const char *local_port)
  38. {
  39.     struct sockaddr_in      server;
  40.     struct sockaddr_in      local;
  41.     struct hostent    * he;
  42.     int              s;
  43.  
  44. #define ERRORRET(n) do { int e=errno;close(s);errno=e;return (n);} while (0)
  45.  
  46.     if (remote_host == NULL  ||  remote_port == NULL) 
  47.     {
  48.     errno = EINVAL;
  49.     return -1;
  50.     }
  51.  
  52.     if ((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
  53.     return -1;
  54.     if (local_host  ||  local_port)
  55.     {
  56.     if (get_inaddr(&local, local_host, local_port, "tcp") < 0)
  57.         ERRORRET(-1);
  58.     if (bind(s, (struct sockaddr*)&local, sizeof local) < 0)
  59.         ERRORRET(-1);
  60.     }
  61.  
  62.     /* Get port */
  63.     if (get_inaddr(&server, NULL, remote_port, "tcp") < 0)
  64.     ERRORRET(-1);
  65.  
  66.     /* Check for numerical IP address */
  67.     server.sin_addr.s_addr = inet_addr(remote_host);
  68.     if (server.sin_addr.s_addr != (unsigned long)-1)
  69.     {
  70.     if (connect(s, (struct sockaddr*)&server, sizeof server) < 0)
  71.         ERRORRET(-1);
  72.     return s;
  73.     }
  74.  
  75.     /*  Not numerical address, then it should be a host name.
  76.      *  gethostbyname() it and try all the hosts addresses.
  77.      */
  78.     if ((he = gethostbyname(remote_host)) == NULL)
  79.     ERRORRET(-1);
  80.     assert(he->h_addrtype == AF_INET);
  81.     assert(he->h_length == sizeof server.sin_addr.s_addr);
  82.  
  83.     server.sin_family = he->h_addrtype;
  84.     {
  85.     char **a = he->h_addr_list;
  86.     while (*a) 
  87.     {
  88.         memcpy(&server.sin_addr, *a, sizeof server.sin_addr);
  89.         if (connect(s, (struct sockaddr*)&server, sizeof server) >= 0)
  90.         return s;
  91.         a++;
  92.     }
  93.     }
  94.     ERRORRET(-1);
  95. }
  96.